/*!
 * dayu_ui
 * 依赖dayuHttp
 * 依赖：ng-context-menu
 * 依赖ui-grid，ng-context-menu
 * Copyright(c) 2016 huangbinglong
 * MIT Licensed
 */

'use strict';

angular.module("dayu.ui.grid",['dayu.ui.http','ng-context-menu'])
    .provider("DayuGrid",function() {
        /**
         * options 中，除了UI-GRID的gridOptions；
         * 还可以配置：getPage(paginationOptions,callback)方法，自定义每一页的查询；
         *      其中paginationOptions为分页信息，callback(total,data)为查询成功后需要回调的方法，需要参数：total长度跟data，
         * bizName属性：配置的业务名称，用于使用DayuHttp
         * @param options
         * @param $scope
         * @constructor
         */
        function DayuGrid (options,$scope) {
            var self = this;
            self._originOptions = options;
            $scope = $scope || {};
            options = angular.copy(options);
            self.$scope = $scope;
            // ui-grid默认配置
            self._paginationOptions = {
                pageNumber: 1,
                pageSize: 10,
                sort: null
            };
            self._options = {};
            if (options.gridOptions.onRegisterApi) {
                self._options.onRegisterApi = options.gridOptions.onRegisterApi;
                delete options.gridOptions.onRegisterApi;
            }
            self._options.gridOptions = {
                paginationPageSizes: [10, 25, 50,100,200],
                paginationPageSize: 10,
                useExternalPagination: true,
                useExternalSorting: true,
                enableGridMenu: true,
                multiSelect:true,
                modifierKeysToMultiSelect:false,
                noUnselect:false,
                exporterMenuAllData: true,
                exporterCsvFilename:'ZwxData.csv',
                exporterMenuPdf:false,
                rowSelection:true,
                enableRowSelection:true,
                enableRowHeaderSelection:true,
                rowTemplate:"<div " +
                "ng-click=\"grid.api.selection.clearSelectedRows();grid.api.selection.selectRow(row.entity)\"" +
                "context-menu=\"grid.api.selection.clearSelectedRows();grid.api.selection.selectRow(row.entity)\" " +
                "target=\"dayuGridContextMenu-\""+$scope.id+" ng-class=\"{'ui-grid-row-header-cell': col.isRowHeader }\"" +
                " ng-repeat=\"(colRenderIndex, col) in colContainer.renderedColumns track by col.uid\" " +
                "ui-grid-one-bind-id-grid=\"rowRenderIndex + '-' + col.uid + '-cell'\" " +
                "role=\"{{col.isRowHeader ? 'rowheader' : 'gridcell'}}\" " +
                "ui-grid-cell class=\"ui-grid-cell\"></div>",
                onRegisterApi: function(gridApi) {
                    self.gridApi = gridApi;
                    self.getPage();  // 查询一页
                    self.gridApi.core.on.sortChanged(self.$scope, function(grid, sortColumns) {
                        if (sortColumns.length === 0) {
                            self._paginationOptions.sort = null;
                        } else {
                            self._paginationOptions.sort = sortColumns[0].sort.direction;
                        }
                        self.getPage();
                    });
                    gridApi.pagination.on.paginationChanged(self.$scope, function (newPage, pageSize) {
                        self._paginationOptions.pageNumber = newPage;
                        self._paginationOptions.pageSize = pageSize;
                        self.getPage();
                    });
                    if (self._options.onRegisterApi) {
                        self._options.onRegisterApi(self);
                    }
                    self._onRegisterDefer.resolve(self);
                },
                exporterAllDataFn:function() {
                    self._loading = true;
                    return self.createDayuHttp().post(self.reqParams()).then(function(allDataRes) {
                        self._options.gridOptions.data = allDataRes.data || [];
                        self._loading = false;
                    });
                }
            };
            this._options = angular.merge({},this._options,options||{});
            return this;
        }

        DayuGrid.prototype.resetScope = function($scope) {
            if ($scope) {
                DayuGrid.call(this,this._originOptions,$scope).build();
            }
            return this;
        };

        DayuGrid.prototype.gridOptions = function() {
            return this._options.gridOptions;
        };

        DayuGrid.prototype.updateColumnDefs = function(columnDefs) {
            this._options.gridOptions.columnDefs = columnDefs;
            return this;
        };

        DayuGrid.prototype.options = function() {
            return this._options;
        };

        DayuGrid.prototype.setReqParams = function(params) {
          this._options.reqParams = params;
            return this;
        };

        DayuGrid.prototype.reqParams = function() {
             return this._options.reqParams || {};
        };

        DayuGrid.prototype.isLoading = function() {
          return !! this._loading;
        };

        DayuGrid.prototype.buildNavigation = function() {
            if (!this._navigation) {
                this._navigation = new Navigation(this);
            }
            return this._navigation;
        };

        DayuGrid.prototype.navigation = function() {
            return this._navigation;
        };


        DayuGrid.prototype.getCurrPage = function() {
            return this._paginationOptions.pageNumber;
        };

        function Navigation(dayuGrid) {
            this._dayuGrid = dayuGrid;
            this._detailUrl = "/detail/";
            this._data = dayuGrid.gridOptions().data;
            this._currentId = undefined;  // 当前ID
        }
        Navigation.prototype.setDetailUrl = function(url) {
            this._detailUrl = url;
            return this;
        };
        Navigation.prototype.setParams = function(json) {
            this._params = json;
            return this;
        };
        Navigation.prototype.params = function() {
            return this._params || {};
        };
        Navigation.prototype.setCurrentId = function(id) {
            this._currentId = id;
            return this;
        };
        Navigation.prototype.hasNext = function() {
            if (this._currentId && this._data) {
                for (var i = 0;i < this._data.length;i++) {
                    if (this._currentId == this._data[i].id && i < this._data.length-1) {
                        return this._data[i+1];
                    }
                }
            } else if (!this._dayuGrid._isBottomPage) {
                return true;
            }
            return false;
        };
        Navigation.prototype.hasPrevious = function() {
            if (this._currentId && this._data) {
                for (var i = 0;i < this._data.length;i++) {
                    if (this._currentId == this._data[i].id && i !== 0) {
                        return this._data[i-1];
                    }
                }
            } else if (!this._dayuGrid._isTopPage) {
                return true;
            }
            return false;
        };
        Navigation.prototype.next = function() {
            var next = this.hasNext();
            if (next && next.id) {
                this._currentId = next.id;
                this.go();
            } else if (next) {
                var self = this;
                this._dayuGrid.getPage(this._dayuGrid._paginationOptions.pageNumber+1,function(data) {
                    if (data && data.length > 0) {
                        self._currentId = data[0].id;
                        self.go();
                    }
                });
            }
        };
        Navigation.prototype.previous = function() {
            var previous = this.hasPrevious();
            if (previous && previous.id) {
                this._currentId = previous.id;
                this.go();
            } else if (previous) {
                var self = this;
                this._dayuGrid.getPage(this._dayuGrid._paginationOptions.pageNumber-1,function(data) {
                    if (data && data.length > 0) {
                        self._currentId = data[data.length -1].id;
                        self.go();
                    }
                });
            }
        };


        this.$get = function(DayuHttp,uiGridConstants,i18nService,$location,$q) {
            //设置中文
            i18nService.setCurrentLang('zh-cn');

            var _getPage = function(cb) {
                var self = this;
                if (!self._options.bizName) {
                    return;
                }
                self._loading = true;
                self._dayuHttp.header({"pageInfo" : {
                    "currPage" : self._paginationOptions.pageNumber - 1,
                    "pageSize" : self._paginationOptions.pageSize
                }}).post(self.reqParams()).then(function(res) {
                    self._loading = false;
                    if(res.total===undefined){
                        self._options.gridOptions.totalItems = res.responseData.total || 0;
                    }else{
                        self._options.gridOptions.totalItems = res.total || 0;
                    }
                    if(res.data===undefined){
                        self._options.gridOptions.data = res.responseData.data || res.responseData || [];
                    }else{
                        self._options.gridOptions.data = res.data || [];
                    }

                    if (self._paginationOptions.pageNumber == 1) {
                        self._isTopPage = true;
                    }
                    if (self._options.gridOptions.totalItems &&
                        (self._options.gridOptions.totalItems/self._paginationOptions.pageSize) <= self._paginationOptions.pageNumber) {
                        self._isBottomPage = true;
                    }
                    if (cb) {
                        cb(self._options.gridOptions.data);
                    }
                },function(res) {
                    self._loading = false;
                    console.log(res);
                });
            };

            DayuGrid.prototype.getPage = function(pageNum,cb) {
                var self = this;
                if (!angular.isUndefined(pageNum)) {
                    self._paginationOptions.pageNumber = pageNum;
                }
                if (self._options.getPage && angular.isFunction(self._options.getPage)) {
                    self._options.getPage(self._paginationOptions,function(total,data) {
                        self._options.gridOptions.totalItems = total;
                        self._options.gridOptions.data = data;
                    });
                } else {
                    _getPage.call(self,cb);
                }
            };

            DayuGrid.prototype.build = function() {
                this._onRegisterDefer = $q.defer();
                this._onRegisterPromise = this._onRegisterDefer.promise;
                this._dayuHttp = this.createDayuHttp();
                return this;
            };

            DayuGrid.prototype.createDayuHttp = function() {
                return DayuHttp(this._options.bizName);
            };

            DayuGrid.prototype.onRegisterApi = function(fn) {
                this._onRegisterPromise.then(fn);
                return this;
            };

            Navigation.prototype.go = function() {
                $location.path(this._detailUrl + this._currentId);
            };

            return function(options,$scope) {
                return new DayuGrid(options||{},$scope).build();
            };
        };
    }).controller("DayuGridController",function($scope,$injector,$parse) {
        var vm = this;
        vm.dayuGrid = $scope.dayuGridContextMenu;
        if (!vm.dayuGrid || !vm.dayuGrid.options().action) { // 没有配置
            return;
        }
        var fireListner = function(menu,oneData,selectedData,params) {
            if (oneData) {  // 有单个对象时，初始化导航
                vm.dayuGrid.buildNavigation().setCurrentId(oneData.id);
            }
            var listens = menu.listens;
            var params = params || {
                    "data": oneData,
                    datas:selectedData,
                    dayuGrid:vm.dayuGrid
                };
            var _fire = function(index) {
                if (index >=  listens.length) {
                    return;
                }
                var retObj = $injector.invoke(listens[index], vm, params);
                if (retObj && retObj.then && angular.isFunction(retObj.then)) {
                    retObj.then(function(res) {
                        params['listen'+index] = res;
                        _fire(index+1);
                    });
                } else {
                    params['listen'+index] = retObj;
                    _fire(index+1);
                }
            };
            if (listens && angular.isArray(listens)) {
                _fire(0);
            }
        };
        vm.triggerAction = function(menu,datas) {
            var selectedData = datas || vm.dayuGrid.gridApi.selection.getSelectedRows();
            var oneData;
            if (selectedData && selectedData.length > 0) {
                oneData = selectedData[0];
            }
            selectedData = selectedData || [];
            fireListner(menu,oneData,selectedData);
        };
        // 是否有动作
        vm.hasAction = function() {
            return Object.getOwnPropertyNames(vm.dayuGrid.options().action).length;
        };

        vm.isShowAction = function(showCondition) {
            if (!showCondition || vm.dayuGrid.gridApi.selection.getSelectedRows().length == 0 ||
                vm.dayuGrid.gridApi.selection.getSelectedRows().length > 1) {
                return true;
            }
            return $parse(showCondition)(vm.dayuGrid.gridApi.selection.getSelectedRows()[0]);
        }

    })
    .directive("dayuGridContextMenu",function () { // 右键菜单指令器
        return {
            restrict: "EA",
            controller: "DayuGridController as vm",
            replace: true,
            template: "<div ng-show='vm.hasAction()' " +
            "id=\"{{'dayuGridContextMenu-'+vm.dayuGrid.$scope.id}}\" " +
            "style=\"z-index:9999;position:fixed;\" class=\"dropdown position-fixed\">" +
            "<ul role=\"menu\" class=\"dropdown-menu\">" +
            "<li ng-repeat=\"(key,menu) in vm.dayuGrid.options().action\" ng-show='vm.isShowAction(menu.show)'>" +
            "<a role=\"menuitem\" tabindex=\"1\" ng-click=\"vm.triggerAction(menu)\">" +
            "{{menu.label}}</a></li>" +
            "</ul></div>",
            transclude: true,
            scope: {
                dayuGridContextMenu: "="
            }
        };
    });
